package com.sui.bigdata.sml.model.controller;

import com.feidee.fdcommon.authorization.AuthorizationVerify;
import com.feidee.fdcommon.authorization.model.AuthorizationModel;
import com.feidee.fdcommon.configuration.CustomConfiguration;
import com.feidee.fdcommon.util.ToolUtils;
import com.sui.bigdata.sml.model.exception.BadInferenceRequestException;
import com.sui.bigdata.sml.model.exception.InferenceException;
import com.sui.bigdata.sml.model.exception.VerifyException;
import com.sui.bigdata.sml.model.model.InferenceRequest;
import com.sui.bigdata.sml.model.model.InferenceResponse;
import com.sui.bigdata.sml.model.service.InferenceService;
import com.sui.bigdata.sml.model.util.Constants;
import com.sui.bigdata.sml.model.util.LogCollector;
import com.sui.bigdata.sml.model.util.Utils;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

/**
 * @author songhaicheng
 * @date 2019/11/7 10:07
 * @description
 * @reviewer
 */
@RestController
@CrossOrigin
@RequestMapping("/model")
@Slf4j
public class ForecastController {

    private static int REQUEST_INTERVAL = CustomConfiguration.getInt(Constants.REQUEST_INTERVAL, 15);

    @Autowired
    InferenceService service;

    @GetMapping("/{token}")
    ResponseEntity hello() {
        // 可用于服务健康检测用
        log.debug("Model 服务健在，感觉良好！");
        return new ResponseEntity<>("Hello World", HttpStatus.OK);
    }

    @PostMapping("/{token}")
    ResponseEntity forecast(@RequestBody String data, HttpServletRequest request) {
        // 先进行鉴权
        InferenceRequest inference = verify(data, request);
        // 接下来进行预测
        MDC.put(Constants.TRACE_ID, inference.getTraceId());
        if (inference.getTotalFeatures() == null || !ToolUtils.isNotNull(inference.getBusId())) {
            throw new BadInferenceRequestException(inference);
        }
        InferenceResponse response;
        if (Utils.isMapEmpty(inference.getMultiFeatures())) {
            response = service.forecast(inference);
        } else {
            response = service.forecasts(inference);
        }
        LogCollector.uploadLog(inference, response);
        MDC.remove(Constants.TRACE_ID);
        if (response.getResult() == null) {
            throw new InferenceException();
        }
        return new ResponseEntity<>(response, HttpStatus.OK);
    }

    private InferenceRequest verify(String data, HttpServletRequest request) {
        if(ToolUtils.isNotNull(data)) {
            AuthorizationModel<InferenceRequest> result = AuthorizationVerify.verify(request, data, REQUEST_INTERVAL, InferenceRequest.class);
            if (result != null && result.getCode() == Constants.VERIFY_SUCCESS_CODE) {
                return result.getData();
            } else {
                log.error("鉴权失败：{}", result != null ? result.getErrMsg() : "未知错误");
                throw new VerifyException();
            }
        } else {
            log.error("预测请求体为空");
            throw new VerifyException();
        }
    }

}
